<template>
  <el-container class="decorate-page" v-loading="loading">
    <el-header class="page-header sa-flex sa-flex-wrap">
      <page-header :pageType="pageType" @changePageType="changePageType" v-model:systemType="systemType"
        v-model:platformType="platformType" :currentCompIndex="currentComp.index"
        @updatePageSetting="onUpdatePageSetting">
        <template #operWrap>
          <div class="oper-button preview" @click="onPreview">
            <el-popover popper-class="sa-popper" trigger="hover" content="预览">
              <template #reference>
                <sa-icon icon="sa-shop-decorate-preview" size="24" />
              </template>
            </el-popover>
          </div>
          <el-button v-auth="'shop.admin.decorate.page.edit'" class="oper-button save" @click="savePage">
            <el-popover popper-class="sa-popper" trigger="hover" content="保存">
              <template #reference>
                <sa-icon icon="sa-shop-decorate-save" size="24" />
              </template>
            </el-popover>
          </el-button>
        </template>
      </page-header>
    </el-header>
    <el-main class="page-main sa-flex">
      <!-- left -->
      <page-left :fromType="route.query.fromType" :pageType="pageType" :templateData="template"
        v-model:compType="currentComp.type" v-model:index="currentComp.index" @pageLeftBack="pageLeftBack"></page-left>
      <!-- center -->
      <div class="main-center sa-flex sa-row-center" @click.self="onUpdatePageSetting">
        <div id="html2canvasWrap" :class="[
          `is-${systemType}`,
          `${platformType}-${template[pageType]?.style?.navbar?.mode}`,
        ]">
          <!-- 头部 -->
          <center-header v-if="pageType != 'basic'" :headerData="template[pageType]" :systemType="systemType"
            :platformType="platformType" :isScroll="isScroll"
            :templateDetailType="templateDetail?.type"></center-header>
          <template v-if="template[pageType]">
            <!-- 基础 -->
            <div v-if="pageType == 'basic'" class="comp-wrap" :style="pageStyle()">
              <basic :type="currentComp.type" :compData="template[pageType][currentComp.type]"
                :allData="template[pageType]" />
            </div>
            <!-- 单页 -->
            <sa-draggable v-if="pageType != 'basic'" class="comp-wrap" :style="pageStyle()"
              v-model="template[pageType].data" item-key="element" :animation="300" :group="{
                name: 'draggableName',
              }" filter=".undraggable" :move="centerMove" @end="centerEnd">
              <template #item="{ element, index }">
                <div class="comp-item" :class="[element.type, currentComp.index == index ? 'is-active' : '']"
                  @click.stop="onSelectComp(index, element.type)">
                  <div class="comp-name">
                    {{ compNameObj[element.type] }}
                  </div>
                  <div class="comp-tools">
                    <el-icon v-if="(pageType == 'home' && index > 0) || (pageType == 'user' && index > 1)"
                      @click.stop="onUpComp(index)">
                      <ArrowUp />
                    </el-icon>
                    <el-icon v-if="index < template[pageType].data.length - 1" @click.stop="onDownComp(index)">
                      <ArrowDown />
                    </el-icon>
                    <el-icon @click.stop="onCopyComp(index)">
                      <CopyDocument />
                    </el-icon>
                    <el-icon @click.stop="onDeleteComp(index)">
                      <Delete />
                    </el-icon>
                    <!-- </div> -->
                  </div>
                  <comp :class="element.type == 'userCard' ? 'undraggable' : ''" v-if="!element.name"
                    :compData="element" />
                </div>
              </template>
            </sa-draggable>
          </template>
          <img v-if="systemType == 'ios'" class="ios-bar" src="/static/images/shop/decorate/ios-bar.png" />
        </div>
      </div>
      <!-- right -->
      <page-right v-model:panelCollapse="panel.rightCollapse" :type="currentComp.type" :rightData="currentComp.right"
        :platformType="platformType" :templateDetailType="templateDetail?.type"></page-right>
    </el-main>
  </el-container>
</template>
<script>
export default {
  name: 'shop.admin.decorate.page',
};
</script>
<script setup>
import {
  getCurrentInstance,
  nextTick,
  onMounted,
  reactive,
  ref,
  onUpdated,
  onBeforeUnmount,
} from 'vue';
import { useModal } from '@/sheep/hooks';
import { useRoute } from 'vue-router';
import SaDraggable from 'vuedraggable';
import html2canvas from 'html2canvas';
import { api } from '../decorate.service';
import fileApi from '@/app/file/api';
import { checkUrl } from '@/sheep/utils/checkUrlSuffix';
import { isEmpty } from 'lodash';
import { compNameObj, initTemplateData, handleTempData, handleSubmitData } from './data';
import pageHeader from './component/pheader.vue';
import pageLeft from './component/left/index.vue';
import pageRight from './component/right/index.vue';
import centerHeader from './component/center/page/navbar.vue';
import basic from './component/center/basic/index.vue';
import comp from './component/center/comp/index.vue';
import { cloneDeep } from 'lodash';
import { ElMessageBox, ElMessage } from 'element-plus';
import PagePreview from './preview.vue';

const { proxy } = getCurrentInstance();
const route = useRoute();

let tempTemplate = {};
let template = reactive({});

let templateId = 0;

const loading = ref(false);

// system/platform
const systemType = ref('android');
const platformType = ref('WechatMiniProgram');

const pageType = ref('basic');
// 当前页面
function changePageType(type) {
  // 保存之前先判断是否修改
  if (JSON.stringify(tempTemplate[pageType.value]) == JSON.stringify(template[pageType.value])) {
    initChangePageData(type);
    pageType.value = type;
    return false;
  }
  ElMessageBox.confirm('是否保存数据', {
    confirmButtonText: '保存',
    cancelButtonText: '放弃',
    type: 'warning',
  })
    .then(async () => {
      // ElMessage({
      //   type: 'success',
      //   message: '保存成功',
      // });
      // 保存
      await savePage();
      // 保存之后清除数据
      await initChangePageData(type, item);
      pageType.value = type;
    })
    .catch(async () => {
      // 放弃清除数据
      await initChangePageData(type);
      pageType.value = type;
    });
}
// 更改页面之后初始化数据
async function initChangePageData(type) {
  // 保存之后清除数据
  currentComp.index = null;
  currentComp.type = null;
  currentComp.right = {};
  // 实时获取最新数据
  pageType.value = type;
  getPage(pageType.value);
}

// 左侧数据赋值
function pageLeftBack(right) {
  currentComp.right = right;
}

// 当前组件
let currentComp = reactive({
  index: null,
  type: null,
  right: {},
});
// 编辑当前组件
function onSelectComp(index, type) {
  currentComp.index = index;
  currentComp.type = type;
  currentComp.right = template[pageType.value].data[currentComp.index];
  panel.rightCollapse = false;

}

function onUpComp(index) {
  template[pageType.value].data.splice(
    index - 1,
    2,
    template[pageType.value].data[index],
    template[pageType.value].data[index - 1],
  );
  onSelectComp(index - 1, template[pageType.value].data[index - 1].type);
}

function onDownComp(index) {
  template[pageType.value].data.splice(
    index,
    2,
    template[pageType.value].data[index + 1],
    template[pageType.value].data[index],
  );
  onSelectComp(index + 1, template[pageType.value].data[index + 1].type);
}

// 复制
function onCopyComp(index) {
  template[pageType.value].data.splice(
    index + 1,
    0,
    cloneDeep(template[pageType.value].data[index]),
  );
  onSelectComp(index + 1, template[pageType.value].data[index].type);
}

// 删除组件
function onDeleteComp(index) {
  template[pageType.value].data.splice(index, 1);
  currentComp.index = null;
  currentComp.type = null;
  currentComp.right = {};
}

// 拖动
function centerMove(e, originalEvent) {
  if (originalEvent.target.className.indexOf('undraggable') != -1) {
    return false;
  }
  if (
    pageType.value == 'user' &&
    e.draggedContext.futureIndex == 0 &&
    e.draggedContext.element.type != 'userCard'
  ) {
    return false;
  }
}
function centerEnd(e) {
  if (currentComp.index) {
    currentComp.index = e.newIndex;
    currentComp.right = template[pageType.value].data[currentComp.index];
    currentComp.type = currentComp.right.type;
  }
}

// 编辑页面
function onUpdatePageSetting() {
  if (pageType.value != 'basic') {
    currentComp.index = -1;
    currentComp.type = 'page';
    currentComp.right = template[pageType.value].style;
  }
}

// 获取页面详情
async function getPage(type = pageType.value) {
  templateId = route.query.id;
  const { data } = await api.getPage(route.query.id, type);
  template[pageType.value] = isEmpty(data) ? initTemplateData[type] : data.page;

  // home user diypage
  if (pageType.value != 'basic') {
    template[pageType.value] = handleTempData(template[pageType.value]);
  }

  // 暂存数据
  tempTemplate[pageType.value] = cloneDeep(template[pageType.value]);
}

// 保存截图
function getHtml2canvas() {
  return new Promise((resolve) => {
    nextTick(() => {
      html2canvas(document.getElementById('html2canvasWrap'), {
        allowTaint: false,
        taintTest: true,
        useCORS: true,
        height: 1000,
        scrollX: 0,
        scrollY: 0,
        // dpi: 100,
        // scale: 0.7,
      }).then(async (canvas) => {
        // let base = canvas.toDataURL('image/png');
        // resolve(base);
        let blob = dataURLToBlob(canvas.toDataURL('image/png'));
        var formData = new FormData();
        let fileOfBlob = new File([blob], new Date() + '.png');
        formData.append('file', fileOfBlob);
        let { data } = await fileApi.upload({ group: 'decorate', savelog: 0 }, formData);
        resolve(data.path);
      });
    });
  });
}

function dataURLToBlob(dataurl) {
  let arr = dataurl.split(',');
  let mime = arr[0].match(/:(.*?);/)[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}

// 保存
async function savePage() {
  loading.value = true;
  let pageCover = {};
  let temp = cloneDeep(template[pageType.value]);

  if (pageType.value != 'basic') {
    pageCover.image = await getHtml2canvas();
    temp = handleSubmitData(temp);
  }

  // if (currentComp.type == 'shopGoodsList') {
  //   temp.data.find((item) => {
  //     if (item.type == currentComp.type) {
  //       item.data.goodsIds = item.data.goodsList.map(i => i.id)
  //     }
  //   })
  // }

  await api.updatePage(route.query.id, pageType.value, {
    page: JSON.stringify(temp),
    ...pageCover,
  });
  // 暂存数据
  tempTemplate[pageType.value] = cloneDeep(template[pageType.value]);
  loading.value = false;
}

// 页面样式
function pageStyle() {
  if (pageType.value != 'basic') {
    if (
      template[pageType.value] &&
      template[pageType.value].style &&
      template[pageType.value].style.background
    ) {
      let css = {
        'background-color': template[pageType.value].style.background.color,
      };
      if (template[pageType.value].style.background.src) {
        css = {
          ...css,
          'background-image':
            'url(' + checkUrl(template[pageType.value].style.background.src) + ')',
        };
      }
      return css;
    }
  }
}

const isScroll = ref(false);
function onScrollChange(val) {
  isScroll.value = val.target.scrollTop ? true : false;
}

function onPreview() {
  useModal(PagePreview, {
    title: '预览',
    data: templateDetail.value,
    class: 'preview-dialog',
  });
}

const templateDetail = ref({});
async function getDetail() {
  const { error, data } = await api.template.detail(route.query.id);
  error === 0 &&
    ((pageType.value = data.type == 'template' ? 'basic' : 'diypage'),
      (templateDetail.value = data));
}

// 面板
const panel = reactive({
  rightCollapse: false,
});

onMounted(async () => {
  await getDetail();
  getPage();
  nextTick(() => {
    // document.getElementById('compMain').addEventListener('scroll', onScrollChange, true);
  });
});

onBeforeUnmount(() => {
  // document.getElementById('compMain').removeEventListener('scroll', onScrollChange);
});

onUpdated(async () => {
  if (templateId != route.query.id) {
    await getDetail();
    getPage();
  }
});
</script>
<style lang="scss">
@import './index.scss';
</style>
